Service Workerに向かってメッセージを送ってService Worker側から返事を返す方法
#Service_Worker #WebブラウザのJavaScript #PWA
やりたいこと
Service Workerにメッセージを送ってレスポンスを受け取りたい。
送るだけでなくてService Workerからなんらかの結果を受け取れるところが大事なところ。
やりかた
以下は送る側。
code:ts
/**
* Send a message to Service Worker
* base: https://googlechrome.github.io/samples/service-worker/post-message/
* @param message
*/
function sendToServiceWorker(message: any): Promise<MessageEvent> {
return new Promise((resolve, reject) => {
if (!("serviceWorker" in navigator)) {
reject(new Error("Service Worker not supported"));
return;
}
if (navigator.serviceWorker.controller === null) {
reject(new Error("navigator.serviceWorker.controller is null"));
return;
}
const messageChannel = new MessageChannel();
messageChannel.port1.onmessage = resolve;
navigator.serviceWorker.controller.postMessage(message, messageChannel.port2);
});
}
TypeScriptの: anyと: Promise<MessageEvent>を取り除けばJavaScriptとして使えるはず。
anyなのはもともと.postMessage(message: any)なのでしょうがない。
MessageChannelを使って返事をService Worker側から返事を受け取れるようになっている。
以下はService Worker側。(受け取って返事をする)
code:sw.js
self.addEventListener('message', (e) => {
// メッセージを受け取る
const message = e.data;
// 何か処理する
...
// 返事を作る
const reply = "this message is from sw.js";
// 返事を返す
e.ports0.postMessage(reply);
});
e.dataは最初のコードのmessageと等しくなる。
replyは今回は文字列だが文字列に限らずJSONなども送れる。
参考
Service Worker postMessage() Sample